package com.ayuku.retail.ui.pembelian;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;

import org.eclipse.nebula.widgets.grid.Grid;
import org.eclipse.nebula.widgets.grid.GridItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

import com.ayuku.commons.AyBigDecimal;
import com.ayuku.commons.AyukuDB;
import com.ayuku.commons.Util;
import com.ayuku.retail.business.stock.StockImpl;
import com.ayuku.retail.persistence.model.Stock;
import com.ayuku.retail.persistence.model.TrxTempSale;
import com.ayuku.retail.ui.stock.StockLookup;

public class InputPembelian extends org.eclipse.swt.widgets.Dialog {

	private Shell dialogShell;
	private Label label1;
	private Label label4;
	private AyBigDecimal txtHarga;
	private Label label2;
	private AyBigDecimal txtQty;
	private Text txtCode;
	private Grid tableData;
	private AyBigDecimal txtSubTotal;
	private int startLocationX = 0;
	private Text txtDesc;
	private Label label3;
	private int startLocationY = 0;
	private Label lblKeterangan;
	private Label label;

	public InputPembelian(Shell parent, int style, Grid tableData,
			AyBigDecimal txtSubTotal) {
		super(parent, style);
		this.tableData = tableData;

		this.txtSubTotal = txtSubTotal;
	}

	public void open() {
		try {
			Shell parent = getParent();
			dialogShell = new Shell(parent, SWT.DIALOG_TRIM
					| SWT.APPLICATION_MODAL);
			dialogShell.setSize(561, 121);

			dialogShell.setLayout(new GridLayout(4, false));

			label2 = new Label(dialogShell, SWT.NONE);
			GridData gd_label2 = new GridData(SWT.LEFT, SWT.BOTTOM, false,
					false, 1, 1);
			gd_label2.widthHint = 54;
			label2.setLayoutData(gd_label2);
			label2.setText("Qty");

			label1 = new Label(dialogShell, SWT.NONE);
			label1.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, false,
					false, 1, 1));
			label1.setText("Kode Barang");

			lblKeterangan = new Label(dialogShell, SWT.NONE);
			lblKeterangan.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM,
					true, false, 1, 1));
			lblKeterangan.setText("Keterangan");
	
			label4 = new Label(dialogShell, SWT.NONE);
			label4.setLayoutData(new GridData(SWT.FILL, SWT.BOTTOM, false,
					false, 1, 1));
			label4.setText("Harga");

			txtQty = new AyBigDecimal(dialogShell, SWT.BORDER);
			GridData gd_txtQty = new GridData(SWT.LEFT, SWT.FILL, false, false,
					1, 1);
			gd_txtQty.widthHint = 50;
			txtQty.setLayoutData(gd_txtQty);
			txtQty.setStringFormatter("###,##0.###");

			txtQty.getOrgComponent().getControl().addFocusListener(
					new FocusAdapter() {
						public void focusGained(FocusEvent evt) {
							txtQtyFocusGained(evt);
						}
					});
			txtQty.addKeyListener(new KeyAdapter() {

				public void keyPressed(KeyEvent evt) {
					txtQtyKeyListener(evt);
				}
			});

			txtQty.setValue(BigDecimal.valueOf(0));

			txtCode = new Text(dialogShell, SWT.BORDER);
			txtCode.addMouseListener(new MouseAdapter() {
				@Override
				public void mouseDoubleClick(MouseEvent arg0) {
					showLookupStock();
					dialogShell.setFocus();
					saveItemToGrid();
				}
			});
			GridData gd_txtCode = new GridData(SWT.FILL, SWT.FILL, false,
					false, 1, 1);
			gd_txtCode.widthHint = 154;
			txtCode.setLayoutData(gd_txtCode);
			txtCode.setTextLimit(20);

			txtCode.addKeyListener(new KeyAdapter() {
				public void keyPressed(KeyEvent evt) {
					txtCodeKeyPressed(evt);
				}
			});

			txtCode.addFocusListener(new FocusAdapter() {
				public void focusGained(FocusEvent evt) {
					txtCode.selectAll();
				}
			});

			txtDesc = new Text(dialogShell, SWT.BORDER);

			txtDesc.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false,
					1, 1));
			txtDesc.setText("");

			txtDesc.setTextLimit(20);
			txtDesc.setEditable(false);
			txtDesc.setEnabled(false);

			txtHarga = new AyBigDecimal(dialogShell, SWT.BORDER);
			GridData gd_txtHarga = new GridData(SWT.FILL, SWT.FILL, false,
					false, 1, 1);
			gd_txtHarga.widthHint = 121;
			txtHarga.setLayoutData(gd_txtHarga);
			txtHarga.setStringFormatter("###,###,##0.##");

			txtHarga.addKeyListener(new KeyAdapter() {
				public void keyPressed(KeyEvent evt) {
					txtHargaKeyPressed(evt);
				}
			});

			label = new Label(dialogShell, SWT.SEPARATOR | SWT.HORIZONTAL);
			label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
					false, 4, 1));

			label3 = new Label(dialogShell, SWT.NONE);
			GridData gd_label3 = new GridData(SWT.LEFT, SWT.BOTTOM, false,
					false, 4, 1);
			gd_label3.heightHint = 21;
			label3.setLayoutData(gd_label3);
			label3.setForeground(com.swtdesigner.SWTResourceManager
					.getColor(SWT.COLOR_BLUE));
			label3
					.setText("Gunakan:    F7= Tampilkan stok,     TAB= pindah antar kolom,       ESC= close");

			startLocationY = tableData.getLocation().y
					+ tableData.getClientArea().height - 40;

			startLocationX = (tableData.getClientArea().width / 2)
					- (dialogShell.getBounds().width / 2);

			dialogShell.setLocation(startLocationX, startLocationY);
			dialogShell.open();
			dialogShell.layout();

			// Util.setSize(dialogShell, 650, 110);

			txtQty.setValue(BigDecimal.valueOf(1));
			txtCode.setFocus();

			Display display = dialogShell.getDisplay();
			while (!dialogShell.isDisposed()) {
				if (!display.readAndDispatch())
					display.sleep();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void setFocusToLastRowItem() {

		Rectangle rect = tableData.getClientArea();
		int itemHeight = tableData.getItemHeight();
		int headerHeight = tableData.getHeaderHeight();
		int visibleItemCount = ((rect.height - headerHeight) / itemHeight) - 1;
		int m = tableData.getItemCount();
		if (m > visibleItemCount) {
			tableData.setTopIndex(m - visibleItemCount);
		}
		if (m > 0) {
			tableData.setSelection(m - 1);
		}

	}

	private void showLookupStock() {

		StockLookup lk = new StockLookup(getParent(), SWT.NONE) {
			public void setForm(TableItem itm) {
				String code = Util.nullToString(itm.getText(0));
				String desc = Util.nullToString(itm.getText(1));
				String strSellingPrice = Util.nullToString(itm.getText(2));
				strSellingPrice = strSellingPrice.replace(",", "");
				txtCode.setText(code);
				txtDesc.setText(desc);
				txtHarga.setValue(BigDecimal.valueOf(Double
						.valueOf(strSellingPrice)));
			}
		};
		lk.open();
	}

	private void saveItemToGrid() {
		if (txtCode.getText() != null && txtDesc.getText() != null
				&& txtHarga.getValue().doubleValue() > 0) {
			populateGridTable(txtCode.getText());
			doPrepareInput();
			setFocusToLastRowItem();
		}
	}

	private void checkCodeToDB(String key) {
		System.out.println("barcode: " + key);
		Stock stk;
		try {
			stk = StockImpl.getByBarcode(key);
			if (stk != null) {
				System.out.println("*** Stock dicari ditemukan");
				txtHarga.setValue(stk.getSellingPrice());
				txtDesc.setText(stk.getName());

				saveItemToGrid();

			} else {
				// txtCode.setText("");
				Util.showMsgBox("Kode barang tidak ada di database!", 1,
						dialogShell);
				// doPrepareInput();
				txtCode.setFocus();
				txtCode.selectAll();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private void populateGridTable(String key) {
		System.out.println("barcode: " + key);
		Stock stk;
		try {
			stk = StockImpl.getByBarcode(key);
			if (stk != null) {
				System.out.println("*** Stock dicari ditemukan");

				TrxTempSale sale = AyukuDB.getPersist().readByPrimaryKey(
						TrxTempSale.class, key.trim());

				if (sale != null) {
					sale.setQty(sale.getQty().add(txtQty.getValue()));
					AyukuDB.getPersist().update(sale);

				} else {

					TrxTempSale n = new TrxTempSale();
					n.setBarcode(stk.getBarcode());
					n.setKeterangan(stk.getName());

					n.setPrice(stk.getSellingPrice());

					n.setQty(txtQty.getValue());

					Integer rowId = AyukuDB.getPersist().read(Integer.class,
							"select max(idx) from trx_temp_sale");
					if (rowId == null) {
						rowId = 0;
					}

					n.setIdx(rowId + 1);

					n.setDisc(stk.getDiscount());

					n.setIpAddress(Util.getIPAddress());
					n.setTotal(BigDecimal.valueOf(0));
					AyukuDB.getPersist().insert(n);
				}

				// recalculate
				doRecalculateRows(key);
				// end of

				doReloadList();
				txtCode.setFocus();
			} else {
				txtCode.setText("");
				Util.showMsgBox("Kode barang tidak ada di database!", 1,
						dialogShell);
				doPrepareInput();
				txtCode.setFocus();
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void doReloadList() throws SQLException {
		List<TrxTempSale> lst = AyukuDB.getPersist().readList(
				TrxTempSale.class, "SELECT * FROM TRX_TEMP_SALE order by idx");
		tableData.removeAll();
		tableData.clearAll(true);
		tableData.setItemCount(lst.size());
		BigDecimal tot = BigDecimal.valueOf(0);
		for (int i = 0; i < lst.size(); i++) {
			TrxTempSale sl = lst.get(i);

			tot = tot.add(sl.getTotal());

			GridItem itm = tableData.getItem(i);
			itm.setText(0, sl.getBarcode());
			itm.setText(1, sl.getKeterangan());
			itm.setText(2, Util.formatToNumber(sl.getPrice()));
			itm.setText(3, Util.formatToNumber(sl.getQty()));
			itm.setText(4, Util.formatToNumber(sl.getDisc()));
			itm.setText(5, Util.formatToNumber(sl.getTotal()));
			itm.setText(6, sl.getIdx() + "");

		}
		txtSubTotal.setValue(tot);
		txtCode.setFocus();
	}

	private void doRecalculateRows(String key) throws SQLException {
		TrxTempSale sold = AyukuDB.getPersist().readByPrimaryKey(
				TrxTempSale.class, key.trim());

		if (sold != null) {
			BigDecimal totalHarga = sold.getQty().multiply(sold.getPrice());
			BigDecimal totalDiskon = (sold.getDisc().divide(BigDecimal
					.valueOf(100))).multiply(totalHarga);
			sold.setTotal(totalHarga.subtract(totalDiskon));
			AyukuDB.getPersist().update(sold);
		}
	}

	private void doPrepareInput() {
		txtCode.setText("");
		txtDesc.setText("");
		txtQty.setValue(BigDecimal.valueOf(1));
		txtHarga.setValue(BigDecimal.valueOf(0));
	}

	private void detectKey(KeyEvent evt) {
		if (evt.keyCode == SWT.F7) {
			showLookupStock();
			dialogShell.setFocus();
			saveItemToGrid();
		} else if (evt.keyCode == SWT.F10) {
			saveItemToGrid();
		}
	}

	private void txtQtyFocusGained(FocusEvent evt) {
		txtQty.getOrgComponent().getControl().selectAll();
	}

	private void txtCodeKeyPressed(KeyEvent evt) {

		if (evt.keyCode == SWT.CR) {
			if (txtCode != null && txtCode.getText().trim().equals("")) {
				Util
						.showMsgBox(
								"Masukkan code barang, atau tekan F7 untuk menampilkan daftar barang.",
								1, dialogShell);
			} else {
				checkCodeToDB(txtCode.getText());
			}
		} else if (evt.keyCode == SWT.ARROW_UP) {
			txtQty.setFocus();
		} else if (evt.keyCode == SWT.ARROW_DOWN) {
			txtHarga.setFocus();
		} else {
			detectKey(evt);
		}
	}

	private void txtHargaKeyPressed(KeyEvent evt) {
		if (evt.keyCode == SWT.CR) {
			txtQty.setFocus();
		} else if (evt.keyCode == SWT.ARROW_UP) {
			txtCode.setFocus();
		} else if (evt.keyCode == SWT.ARROW_DOWN) {
			txtQty.setFocus();
		} else {
			detectKey(evt);
		}
	}

	protected void txtQtyKeyListener(KeyEvent evt) {

		if (evt.keyCode == SWT.CR) {
			txtCode.setFocus();
		} else if (evt.keyCode == SWT.ARROW_UP) {
			txtHarga.setFocus();
		} else if (evt.keyCode == SWT.ARROW_DOWN) {
			txtCode.setFocus();
		} else {
			detectKey(evt);
		}

	}
}
